﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace PlanningGIS.Util.Drawing
{
    /// <summary>
    /// 
    /// </summary>
    public class ImageHelper
    {
        /// <summary>
        /// 以行列式将多张图片合并成一张图片。
        /// 图片集的存放方式为：
        /// 1、2、3、4
        /// 5、6、7、8
        /// ...
        /// </summary>
        /// <param name="column">图片集的行数</param>
        /// <param name="row">图片集的的列数</param>
        /// <param name="imageWidth">图片的宽度</param>
        /// <param name="imageHeight">图片的高度</param>
        /// <param name="images">图片集合</param>
        /// <returns></returns>
        public static Image Merge(int column, int row, int imageWidth, int imageHeight, List<byte[]> images)
        {
            if (column < 1 || row < 1)
                throw new Exception("行数或列数不能小于1。");
            if (column * row != images.Count)
                throw new Exception("图片数量与行列数不一致，行*列=图片数。");
            int width = imageWidth * column;
            int height = imageHeight * row;
            Bitmap bitmap = new Bitmap(width, height);
            Graphics graphics = Graphics.FromImage(bitmap);
            int x = 0;
            int y = 0;
            int index = 0;
            for (int i = 0; i < column; i++)
            {
                y = imageHeight * i;
                for (int j = 0; j < row; j++)
                {
                    x = imageWidth * j;
                    Image img = BytesToBitmap(images[index]);
                    if (img != null)
                    {
                        Rectangle rect = new Rectangle(x, y, imageWidth, imageHeight);
                        graphics.SetClip(rect);
                        graphics.DrawImage(img, rect);
                    }
                    index += 1;
                }
            }
            graphics.ResetClip();
            return bitmap;
        }
        /// <summary>
        /// 以行列式将多张图片合并成一张图片。
        /// 图片集的存放方式为：
        /// 1、2、3、4
        /// 5、6、7、8
        /// ...
        /// </summary>
        /// <param name="column">图片集的行数</param>
        /// <param name="row">图片集的的列数</param>
        /// <param name="imageWidth">图片的宽度</param>
        /// <param name="imageHeight">图片的高度</param>
        /// <param name="images">图片集合</param>
        /// <returns></returns>
        public static Image Merge(int column, int row, int imageWidth, int imageHeight, List<Image> images)
        {
            if (column < 1 || row < 1)
                throw new Exception("行数或列数不能小于1。");
            if (column * row != images.Count)
                throw new Exception("图片数量与行列数不一致，行*列=图片数。");
            int width = imageWidth * column;
            int height = imageHeight * row;
            Bitmap bitmap = new Bitmap(width, height);
            Graphics graphics = Graphics.FromImage(bitmap);
            int x = 0;
            int y = 0;
            int index = 0;
            for (int i = 0; i < column; i++)
            {
                y = imageHeight * i;
                for (int j = 0; j < row; j++)
                {
                    x = imageWidth * j;
                    Image img = images[index];
                    if (img != null)
                    {
                        Rectangle rect = new Rectangle(x, y, imageWidth, imageHeight);
                        graphics.SetClip(rect);
                        graphics.DrawImage(img, rect);
                    }
                    index += 1;
                }
            }
            graphics.ResetClip();
            Image saveImage = Image.FromHbitmap(bitmap.GetHbitmap());
            bitmap.Dispose();
            graphics.Dispose();
            return saveImage;
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="image"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Image Clip(Image image, int x, int y, int width, int height)
        {
            if (image == null)
                return null;
            int w = image.Width;
            int h = image.Height;
            if (x > w || y > h)
                return null;
            if (x == 0 && y == 0 && width == w && height == h)
                return image;
            if (x + width > w)
                width = w - x;
            if (y + height > h)
                height = h - y;
            Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            Graphics graphics = Graphics.FromImage(bitmap);
            Rectangle aim = new Rectangle(0, 0, width, height);
            Rectangle src = new Rectangle(x, y, width, height);
            graphics.DrawImage(image, aim, src, GraphicsUnit.Pixel);
            graphics.Dispose();
            return bitmap;
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="image"></param>
        /// <param name="newWidth"></param>
        /// <param name="newHeight"></param>
        /// <returns></returns>
        public static Image Resize(Image image, int newWidth, int newHeight)
        {
            if (image.Width == newWidth && image.Height == newHeight)
                return image;
            Bitmap b = new Bitmap(newWidth, newHeight);
            Graphics g = Graphics.FromImage(b);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            Rectangle aim = new Rectangle(0, 0, newWidth, newHeight);
            Rectangle src = new Rectangle(0, 0, image.Width, image.Height);
            g.DrawImage(image, aim, src, GraphicsUnit.Pixel);
            g.Dispose();
            return b;
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static byte[] BitmapToBytes(Bitmap bitmap, System.Drawing.Imaging.ImageFormat format)
        {
            System.Drawing.Image photo = (Image)bitmap;
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            photo.Save(ms, format);
            return ms.GetBuffer();
        }
        
        /// <summary>
        /// 将byte流转成图片
        /// </summary>
        /// <param name="images">要转换的byte流</param>
        /// <returns></returns>
        public static Image BytesToBitmap(byte[] images)
        {
            MemoryStream stream = new MemoryStream(images);
            Image img = Image.FromStream(stream, true);
            return img;
        }

        /// <summary>
        /// 将图片转成byte流
        /// </summary>
        /// <param name="image">要转换的图片对象</param>
        /// <param name="imgtype">图片类型</param>
        /// <returns></returns>
        public static byte[] BitmaToByte(Image image, System.Drawing.Imaging.ImageFormat imgtype)
        {
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            image.Save(ms, imgtype);
            byte[] bytes = ms.GetBuffer();
            ms.Dispose();
            ms = null;
            return bytes;
        }
        /// <summary>
        /// 获取验证码图片
        /// </summary>
        /// <param name="code">验证码</param>
        /// <returns></returns>
        public static System.Drawing.Bitmap CodeImage(string code)
        {
            if (string.IsNullOrEmpty(code))
                return null;
            System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling(code.Length * 12.0), 22);
            Graphics g = Graphics.FromImage(image);
            g.Clear(Color.White);
            //画图片的背景噪音线
            Random rdm = new Random();
            for (int i = 0; i < 3; i++)
            {
                int x1 = rdm.Next(image.Width);
                int x2 = rdm.Next(image.Width);
                int y1 = rdm.Next(image.Height);
                int y2 = rdm.Next(image.Height);
                g.DrawLine(new Pen(Color.Black), x1, y1, x2, y2);
            }
            Font font = new System.Drawing.Font("Arial", 12, FontStyle.Bold);
            g.DrawString(code, font, new SolidBrush(Color.Red), 2, 2);
            //画前景噪音线
            for (int i = 0; i < 100; i++)
            {
                int x = rdm.Next(image.Width);
                int y = rdm.Next(image.Height);
                image.SetPixel(x, y, Color.FromArgb(rdm.Next()));
            }
            g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
            return image;
        }
        
        /// <summary>
        /// 获取把图片按比例缩放到规定的大小以内的大小
        /// </summary>
        /// <param name="img">目标图片</param>
        /// <param name="maxSize">最大大小</param>
        /// <returns></returns>
        public static Size GetLimitSize(Image img, Size maxSize)
        {
            Size size = new Size();
            //如果需要缩放
            if (img.Width > maxSize.Width || img.Height > maxSize.Height)
            {
                //获取高宽比
                double hwRateNow = (Convert.ToDouble(img.Height) / img.Width);
                double hwRateMax = (Convert.ToDouble(maxSize.Height) / maxSize.Width);

                //如果高度要缩小
                if (hwRateNow > hwRateMax)
                {
                    size.Height = maxSize.Height;
                    size.Width = Convert.ToInt32(size.Height / hwRateNow);
                }
                //缩小宽度
                else
                {
                    size.Width = maxSize.Width;
                    size.Height = Convert.ToInt32(size.Width * hwRateNow);
                }

            }
            //否则图片大小不变
            else
            {
                size = img.Size;
            }
            return size;
        }

        /// <summary>
        /// 在图片中添加文字
        /// </summary>
        /// <param name="image">图片</param>
        /// <param name="value">要添加的文字</param>
        /// <returns></returns>
        public static Image AddText(Image image, string value)
        {
            //单色文字
            //Graphics myg = pictureBox1.CreateGraphics();              //创建Graphics对象案例
            //SolidBrush mybrush = new SolidBrush(Color.Red);          //定义画笔类型及颜色
            //Font myfont = new Font("黑体", 20);                      //设置字体类型及颜色
            ////调用DrawString方法在图像上写文字
            //myg.DrawString(textBox1.Text, myfont, mybrush, new Rectangle(120, 5, 280, 120));

            //渐变文字
            //Graphics myg = pictureBox1.CreateGraphics();
            ////定义线型渐变画笔
            //LinearGradientBrush mybrush = new LinearGradientBrush(ClientRectangle, Color.Yellow, Color.Red, LinearGradientMode.BackwardDiagonal);
            //Font myfont = new Font("隶书", 25);
            //myg.DrawString(textBox1.Text, myfont, mybrush, new Rectangle(120, 50, 280, 100));

            if (image == null || string.IsNullOrEmpty(value))
                return image;
            //还需要判断文件类型是否为图像类型
            Bitmap bitmap = new Bitmap(image, image.Width, image.Height);
            Graphics g = Graphics.FromImage(bitmap);
            float fontsize = 48; //字体大小 
            float textwidth = value.Length * fontsize; //文本的长度 
            //下面定义一个矩形区域，以后在这个矩形里画上白底黑字 
            float rectx = 10;
            float recty = 10;
            float rectwidth = value.Length * (fontsize + 8);
            float rectheight = fontsize + 8; //声明矩形域 
            RectangleF textarea = new RectangleF(rectx, recty, rectwidth, rectheight);
            Font font = new Font("宋体", fontsize); //定义字体 
            Brush whitebrush = new SolidBrush(Color.Red); //白笔刷，画文字用 
            Brush blackbrush = new SolidBrush(Color.White); //黑笔刷，画背景用 
            g.FillRectangle(blackbrush, rectx, recty, rectwidth, rectheight);
            g.DrawString(value, font, whitebrush, textarea);
            MemoryStream ms = new MemoryStream(); //保存为jpg类型 
            bitmap.Save(ms, ImageFormat.Jpeg); //输出处理后的图像，这里为了演示方便，我将图片显示在页面中了 

            return bitmap;
            //bitmap.Save(fullname, ImageFormat.Jpeg); //保存到磁盘上 
            //System.Web.HttpContext.Current.Response.Clear();
            //System.Web.HttpContext.Current.Response.ContentType = "image/jpeg";
            //System.Web.HttpContext.Current.Response.BinaryWrite(ms.ToArray());
            //g.Dispose();
            //bitmap.Dispose();
            //image.Dispose();
        }

        //private Bitmap destBitmap;
        //private double zoomFactor = 1;
        //private Int32 screenImageWidth = 0;
        //private Int32 screenImageHeight = 0;

        //private void zoom(Image img, double factor)//将图像缩放至当前图像的指定倍数
        //{
        //    using (Bitmap sourceBitmap = new Bitmap(img))
        //    {
        //        //this.zoomFactor = factor;
        //        //Bitmap sourceBitmap = new Bitmap(img);
        //        //destBitmap = new Bitmap((int)Math.Round((double)(sourceBitmap.Width * factor)), (int)Math.Round((double)(sourceBitmap.Height * factor)));
        //        //Graphics.FromImage(destBitmap).DrawImage(sourceBitmap, 0, 0, (int)(destBitmap.Width + 1), (int)(destBitmap.Height + 1));
        //        //this.screenImageWidth = destBitmap.Width;
        //        //this.screenImageHeight = destBitmap.Height;
        //        //this.MainImage.Image = destBitmap;
        //    }
        //}
        ///// <summary>
        ///// 缩小图片
        ///// </summary>
        ///// <param name="source"></param>
        ///// <param name="thumbWi"></param>
        ///// <param name="thumbHi"></param>
        ///// <param name="maintainAspect">保持纵横</param>
        ///// <returns></returns>
        //public Bitmap CreateThumbnail(Bitmap source, int thumbWi, int thumbHi, bool maintainAspect)
        //{
        //    if (source.Width < thumbWi && source.Height < thumbHi)
        //        return source;
        //    Bitmap ret;
        //    try
        //    {
        //        int wi = thumbWi;
        //        int hi = thumbHi;
        //        if (maintainAspect)
        //        {
        //            if (source.Width > source.Height)
        //            {
        //                wi = thumbWi;
        //                hi = (int)(source.Height * ((decimal)thumbWi / source.Width));
        //            }
        //            else
        //            {
        //                hi = thumbHi;
        //                wi = (int)(source.Width * ((decimal)thumbHi / source.Height));
        //            }
        //        }
        //        ret = new Bitmap(wi, hi);
        //        using (Graphics g = Graphics.FromImage(ret))
        //        {
        //            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        //            g.FillRectangle(Brushes.White, 0, 0, wi, hi);
        //            g.DrawImage(source, 0, 0, wi, hi);
        //        }
        //    }
        //    catch
        //    {
        //        ret = null;
        //    }
        //    return ret;
        //}
    }
}
